use crate::{AsyncHandle, Event, EventHandle, EventTrigger, Handle, Schedule};
use std::collections::HashMap;
use std::sync::Arc;

#[derive(Default)]
pub struct EventSchedule {
    events: HashMap<u64, Vec<Arc<dyn EventHandle>>>,
}

impl EventSchedule {
    pub fn register<T, F>(self, handle: F) -> Self
    where
        T: EventTrigger,
        F: AsyncHandle<T> + Sync + Send + 'static,
    {
        self.register_event_handle(Handle::<T, F>::new(handle))
    }
    pub fn register_event_handle<E: EventHandle + 'static>(self, handle: E) -> Self {
        let et_id = handle.event_type_id();
        self.register_event_handle_raw(et_id, handle)
    }
    pub fn register_event_handle_raw<E: EventHandle + 'static>(
        mut self,
        event_type_id: u64,
        handle: E,
    ) -> Self {
        let eh = Arc::new(handle);
        if let Some(ehs) = self.events.get_mut(&event_type_id) {
            ehs.push(eh);
            return self;
        }
        self.events.insert(event_type_id, vec![eh]);
        self
    }
    pub fn build(self) -> Event<Self> {
        return Event::new(self);
    }
}

impl Schedule for EventSchedule {
    fn schedule(&self, trigger_type_id: u64) -> Vec<Arc<dyn EventHandle>> {
        match self.events.get(&trigger_type_id) {
            None => vec![],
            Some(list) => list.clone(),
        }
    }
}
